from typing import Dict, Any, List
from .base_agent import BaseAgent
from utils import logger, CodeAnalyzer
import json

class ReviewerAgent(BaseAgent):
    """代码审查员代理 - 负责代码质量审查和改进建议"""
    
    def __init__(self):
        super().__init__(
            name="代码审查员",
            role="高级代码审查专家"
        )
        self.code_analyzer = CodeAnalyzer()
    
    def _get_system_prompt(self) -> str:
        return """你是一个资深的代码审查专家，具有以下专业技能：

🔍 **审查标准**：
- 代码质量和可读性
- 性能优化和算法效率
- 安全漏洞和潜在风险
- 设计模式和架构合理性
- 代码规范和最佳实践

📊 **审查方法**：
- 静态代码分析
- 复杂度评估
- 代码重复检测
- 依赖关系分析
- 测试覆盖率评估

🛡️ **安全审查**：
- 输入验证检查
- SQL注入防护
- XSS攻击防护
- 权限控制审查
- 敏感信息泄露检查

⚡ **性能审查**：
- 算法复杂度分析
- 内存使用优化
- 数据库查询优化
- 缓存策略评估
- 并发处理优化

📝 **改进建议**：
- 具体的修改建议
- 重构方案
- 性能优化方案
- 安全加固措施
- 可维护性提升

请提供专业、详细、可操作的审查意见。用中文回复。"""
    
    def process(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
        """审查代码质量并提供改进建议"""
        generated_code = input_data.get('generated_code', '')
        code_files = input_data.get('code_files', {})
        test_results = input_data.get('test_results', {})
        
        if not generated_code and not code_files:
            return {
                'success': False,
                'error': '未提供待审查的代码'
            }
        
        # 如果没有解析的代码文件，尝试从生成的代码中解析
        if not code_files and generated_code:
            code_files = {'main.py': generated_code}
        
        # 分析代码统计信息
        code_analysis = {}
        for file_path, code_content in code_files.items():
            analysis = self._analyze_code_file(code_content)
            code_analysis[file_path] = analysis
        
        # 构造审查提示
        prompt = f"""
请对以下代码进行全面的质量审查：

**代码文件**：
{self._format_code_files(code_files)}

**代码统计**：
{self._format_code_analysis(code_analysis)}

**测试结果**：
{str(test_results) if test_results else '暂无测试结果'}

**请进行全面审查，包括**：

## 1. 代码质量评估
- 代码结构和组织
- 命名规范和可读性
- 注释和文档质量
- 错误处理完整性
- 总体质量评分（1-10分）

## 2. 性能分析
- 算法复杂度评估
- 内存使用效率
- 潜在性能瓶颈
- 优化建议

## 3. 安全审查
- 输入验证检查
- 潜在安全漏洞
- 权限控制问题
- 敏感信息处理

## 4. 设计模式评估
- 架构设计合理性
- 设计模式使用
- 模块耦合度
- 可扩展性分析

## 5. 具体改进建议
按优先级列出具体的改进建议：
- 🔴 严重问题（必须修复）
- 🟡 重要改进（建议修复）
- 🟢 优化建议（可选）

## 6. 重构建议
如果需要重构，请提供：
- 重构原因
- 重构方案
- 预期效果

请提供详细、专业的审查报告。
"""
        
        try:
            review_report = self._call_llm(prompt)
            
            # 生成审查摘要
            summary = self._generate_review_summary(code_analysis, review_report)
            
            return {
                'success': True,
                'review_report': review_report,
                'code_analysis': code_analysis,
                'review_summary': summary,
                'summary': f'代码审查完成，发现{summary["total_files"]}个文件的问题'
            }
            
        except Exception as e:
            logger.error(f"代码审查失败: {e}")
            return {
                'success': False,
                'error': str(e),
                'summary': '代码审查失败'
            }
    
    def _analyze_code_file(self, code_content: str) -> Dict[str, Any]:
        """分析单个代码文件"""
        try:
            # 使用模型分析代码
            analysis_prompt = f"""
你是一个代码分析专家。请分析以下代码文件，并以JSON格式返回分析结果。

代码文件：
```python
{code_content}
```

你必须严格按照以下JSON格式返回分析结果，不要添加任何其他内容：
{{
    "stats": {{
        "total_lines": 0,
        "function_count": 0,
        "class_count": 0,
        "import_count": 0,
        "complexity_score": 0
    }},
    "functions": [
        {{
            "name": "",
            "parameters": [],
            "line_number": 0,
            "docstring": "",
            "decorators": []
        }}
    ],
    "classes": [
        {{
            "name": "",
            "methods": [],
            "line_number": 0,
            "docstring": "",
            "base_classes": []
        }}
    ],
    "quality_metrics": {{
        "complexity": 0,
        "maintainability": 0,
        "testability": 0,
        "documentation": 0
    }}
}}

重要提示：
1. 你的回复必须是一个有效的JSON字符串
2. 不要添加任何解释、说明或其他文本
3. 所有数值必须是数字类型（不要用字符串）
4. 所有字符串必须用双引号（不要用单引号）
5. 不要使用任何注释
6. 不要使用任何换行符或空格（除了JSON格式必需的）
7. 确保JSON格式完全正确，可以被json.loads()解析
"""
            
            analysis = self._call_llm(analysis_prompt)
            
            # 尝试清理响应中的非JSON内容
            analysis = analysis.strip()
            if analysis.startswith('```json'):
                analysis = analysis[7:]
            if analysis.endswith('```'):
                analysis = analysis[:-3]
            analysis = analysis.strip()
            
            try:
                return json.loads(analysis)
            except json.JSONDecodeError as e:
                logger.error(f"JSON解析失败: {e}")
                logger.error(f"原始响应: {analysis}")
                # 返回默认值
                return {
                    'error': f"JSON解析失败: {e}",
                    'stats': {},
                    'functions': [],
                    'classes': [],
                    'quality_metrics': {}
                }
            
        except Exception as e:
            logger.error(f"代码分析失败: {e}")
            return {
                'error': str(e),
                'stats': {},
                'functions': [],
                'classes': [],
                'quality_metrics': {}
            }
    
    def _calculate_quality_metrics(self, code_content: str) -> Dict[str, Any]:
        """计算代码质量指标"""
        lines = code_content.split('\n')
        
        # 注释率
        comment_lines = sum(1 for line in lines if line.strip().startswith('#'))
        comment_ratio = (comment_lines / len(lines)) * 100 if lines else 0
        
        # 空行率
        empty_lines = sum(1 for line in lines if not line.strip())
        empty_ratio = (empty_lines / len(lines)) * 100 if lines else 0
        
        # 长函数检测（超过50行的函数）
        long_functions = []
        try:
            functions = self.code_analyzer.extract_functions(code_content)
            for func in functions:
                # 简单估算函数长度（实际应该通过AST精确计算）
                func_lines = code_content.count(f"def {func['name']}")
                if func_lines > 50:  # 这是一个简化的检测
                    long_functions.append(func['name'])
        except:
            pass
        
        return {
            'comment_ratio': round(comment_ratio, 2),
            'empty_ratio': round(empty_ratio, 2),
            'long_functions': long_functions,
            'total_lines': len(lines),
            'code_lines': len(lines) - empty_lines - comment_lines
        }
    
    def _format_code_files(self, code_files: Dict[str, str]) -> str:
        """格式化代码文件为字符串"""
        formatted = ""
        for file_path, content in code_files.items():
            formatted += f"\n--- {file_path} ---\n{content[:1000]}..."  # 限制长度
            if len(content) > 1000:
                formatted += f"\n[文件内容已截断，总长度: {len(content)} 字符]\n"
        return formatted
    
    def _format_code_analysis(self, code_analysis: Dict[str, Any]) -> str:
        """格式化代码分析结果"""
        formatted = ""
        for file_path, analysis in code_analysis.items():
            stats = analysis.get('stats', {})
            quality = analysis.get('quality_metrics', {})
            
            formatted += f"\n--- {file_path} 统计 ---\n"
            formatted += f"总行数: {stats.get('lines', 0)}\n"
            formatted += f"函数数: {stats.get('functions', 0)}\n"
            formatted += f"类数: {stats.get('classes', 0)}\n"
            formatted += f"复杂度: {stats.get('complexity_score', 0)}\n"
            formatted += f"注释率: {quality.get('comment_ratio', 0)}%\n"
            
        return formatted
    
    def _generate_review_summary(self, code_analysis: Dict[str, Any], review_report: str) -> Dict[str, Any]:
        """生成审查摘要"""
        total_files = len(code_analysis)
        total_functions = sum(len(analysis.get('functions', [])) for analysis in code_analysis.values())
        total_classes = sum(len(analysis.get('classes', [])) for analysis in code_analysis.values())
        
        # 简单的问题级别统计（基于关键词）
        critical_issues = review_report.count('🔴') + review_report.count('严重')
        major_issues = review_report.count('🟡') + review_report.count('重要')
        minor_issues = review_report.count('🟢') + review_report.count('优化')
        
        return {
            'total_files': total_files,
            'total_functions': total_functions,
            'total_classes': total_classes,
            'critical_issues': critical_issues,
            'major_issues': major_issues,
            'minor_issues': minor_issues,
            'overall_quality': 'good' if critical_issues == 0 else 'needs_improvement'
        }
    
    def suggest_refactoring(self, code: str) -> str:
        """提供重构建议"""
        prompt = f"""
请为以下代码提供重构建议：

```python
{code}
```

分析并提供：
1. 代码味道识别
2. 重构机会分析
3. 具体重构步骤
4. 重构后的示例代码
5. 重构的风险评估

请详细说明重构的理由和好处。
"""
        
        return self._call_llm(prompt) 